package tp.badugi.client;

import tp.badugi.net.GameStatus;
import tp.badugi.net.iRequestListener;
import tp.badugi.net.iStatusUpdateListener;

public class GameListener implements iRequestListener, iStatusUpdateListener {

	ClientBridgeAdapter clientBridgeAdapter;
	
	public GameListener(ClientBridgeAdapter adapter){
		this.clientBridgeAdapter = adapter;
	}
	
	@Override
	public void actionRequested(String[] possibleActions,
			long betAmount, long minBet, int timeout) {
		this.clientBridgeAdapter.gameStatus.betAmount = betAmount;
		
		this.clientBridgeAdapter.updateGameStatus();
		
		this.clientBridgeAdapter.passActionRequest(possibleActions,timeout);
	}

	@Override
	public void cardsRequested(String[] currentCards, int timeout) {
		this.clientBridgeAdapter.gameStatus.myCards = currentCards;
		
		this.clientBridgeAdapter.updateGameStatus();
		
		this.clientBridgeAdapter.passCardRequest(timeout);
	}

	@Override
	public void receivedCards(String[] cards) {
		//always 4 cards (no exchange = your current cars received);
		
		String[] currentCards = this.clientBridgeAdapter.gameStatus.myCards;
		
		if(currentCards == cards){
			this.clientBridgeAdapter.gameStatus.myCards = cards;
			this.clientBridgeAdapter.updateGameStatus();
		}
		else{
			this.clientBridgeAdapter.gameStatus.myCards = cards;
			this.clientBridgeAdapter.updateGameAndConsole("New cards recieived.");
		}
	}

	@Override
	public void playerJoined(int playerIndex, GameStatus gameStatus) {
		
		this.clientBridgeAdapter.gameStatus = gameStatus;
		
		String playerName = gameStatus.playerNames[playerIndex];
		this.clientBridgeAdapter.updateGameAndConsole(playerName + " has joined the game.");
	}

	@Override
	public void playerLeft(String playerName, GameStatus gameStatus) {
		
		this.clientBridgeAdapter.gameStatus = gameStatus;
		
		this.clientBridgeAdapter.updateGameAndConsole(playerName + " has left the game.");
	}

	@Override
	public void playerDisconnected(String playerName) {		
		this.clientBridgeAdapter.updateGameAndConsole(playerName + " has disconnected.");
	}

	@Override
	public void playerReconnected(String playerName) {
	}

	@Override
	public void playerInActionChanged(int playerIndex, String[] playerNames) {
		this.clientBridgeAdapter.gameStatus.playerInAction = playerIndex;
		
		this.clientBridgeAdapter.updateGameAndConsole(playerNames[playerIndex] + " is now in action.");
	}

	@Override
	public void playerWithButtonChanged(int playerIndex, String[] playerNames) {
		String dealerName = this.clientBridgeAdapter.gameStatus.playerNames[playerIndex];

		this.clientBridgeAdapter.gameStatus.playerWithDealerButton = playerIndex;
		
		this.clientBridgeAdapter.updateGameAndConsole(dealerName + " is dealing cards now.");
	}

	@Override
	public void playerPerformedAction(int playerIndex, String action, long chipBet,
			GameStatus gameStatus) {
		String consoleMessage = gameStatus.playerNames[playerIndex];
			
		switch(action){
			case iRequestListener.ACTION_FOLD : consoleMessage += " folded.";
				break;
			case iRequestListener.ACTION_CHECK : consoleMessage += " checked.";
				break;
			case iRequestListener.ACTION_BET : consoleMessage += " bet " + chipBet + ".";
				break;
			case iRequestListener.ACTION_CALL : consoleMessage += " called.";
				break;
			case iRequestListener.ACTION_RAISE : consoleMessage += " raised by by " + chipBet + ".";
				break;
			case iRequestListener.ACTION_ALLIN : consoleMessage += " went \"All in\"! Bet raised by " + chipBet + ".";
				break;
			default : consoleMessage += " [UNDEFINED_ACTION] [" + chipBet + "]" ;
				break;
		}
		
		this.clientBridgeAdapter.gameStatus = gameStatus;
		
		this.clientBridgeAdapter.updateGameAndConsole(consoleMessage);
	}

	@Override
	public void playerReplacedCards(String playerName, int replacedCardAmount) {
		String consoleMessage = playerName + " exchanged ";
		
		switch(replacedCardAmount){
			case 1 : consoleMessage += replacedCardAmount + " card.";
				break;
			case 0: case 2: case 3: case 4: consoleMessage += replacedCardAmount + " cards.";
				break;
			default : consoleMessage += " [UNIDENTIFIED CARDS NUMBER]";
				break;
		}
		
		this.clientBridgeAdapter.updateGameAndConsole(consoleMessage);
	}

	@Override
	public void bettingRoundChanged(int bettingRound) {
		String consoleMessage;
		
		this.clientBridgeAdapter.gameStatus.bettingRound = bettingRound;
		
		switch(bettingRound){
			case 1: case 2: case 3 : consoleMessage = "Betting round " + bettingRound + " starts.";
				break;
			case 4 : consoleMessage = "Last betting round begins.";
				break;
			default : consoleMessage = "[UNIDENTIFIED ERROR]";
				break;
		}
		
		this.clientBridgeAdapter.updateGameAndConsole(consoleMessage);
	}

	@Override
	public void winnerRevealed(int[] winnerIndexes,
			String[] playerNames, String[][] revealedCards,
			long[] updatedChipCounts) {
		
		//String[playerIndex][cardIndex]
		
		String consoleMessage = "";
		long[] chipsAddedFromPot = new long[updatedChipCounts.length];
		
		for (int i = 0; i < winnerIndexes.length; i++){
			consoleMessage += playerNames[winnerIndexes[i]] + " ";
		}
		consoleMessage += " won the deal!";
		
		chipsAddedFromPot = this.wonAndCurrentChipDifference(
				this.clientBridgeAdapter.gameStatus.playerChipCounts, updatedChipCounts);
		
		this.clientBridgeAdapter.gameStatus.playerChipCounts = updatedChipCounts;
		
		this.clientBridgeAdapter.updateGameAndConsole(consoleMessage);
		
		this.clientBridgeAdapter.passWinnerView(revealedCards, playerNames, chipsAddedFromPot, winnerIndexes);
	}
	
	@Override
	public void connectionLostWithServer() {
		this.clientBridgeAdapter.passErrorMessage("Connection with server lost!");

		this.clientBridgeAdapter.emergrncyClientReset();
	}

	@Override
	public void gameAboutToStart(int timeUntilStart, GameStatus gameStatus) {
		String consoleMessage = "Gameplay will start in " + timeUntilStart + " seconds...";
		
		this.clientBridgeAdapter.gameStatus = gameStatus;
		
		this.clientBridgeAdapter.updateGameAndConsole(consoleMessage);
	}
	
	@Override
	public void gameAboutToRestart(int timeUntilRestart) {
		String consoleMessage = "Gameplay will restart in " + timeUntilRestart + " seconds...";
		
		this.clientBridgeAdapter.updateGameAndConsole(consoleMessage);
	}
	
	
	//----------- Helper methods
	
	private long[] wonAndCurrentChipDifference(long[] currentChips, long[] updatedChips){
		
		long[] amountsWon = updatedChips.clone();
		
		for(int i = 0; i < currentChips.length; i++){
			amountsWon[i] -= currentChips[i];
		}
		
		return amountsWon;
	}

}

		
